home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / c / unixfsys.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-07  |  13.7 KB  |  696 lines

  1. /*
  2.  Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
  3.  
  4. This file is part of GNU Common Lisp, herein referred to as GCL
  5.  
  6. GCL is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GCL is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
  14. License for more details.
  15.  
  16. You should have received a copy of the GNU Library General Public License 
  17. along with GCL; see the file COPYING.  If not, write to the Free Software
  18. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. */
  21.  
  22. #define IN_UNIXFSYS
  23. #include "include.h"
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #include <pwd.h>
  27.  
  28.  
  29. #define    MAXPATHLEN    1024
  30.  
  31.  
  32. #ifdef NEED_GETWD
  33. #include <sys/dir.h>
  34.  
  35.  
  36. #ifndef GETCWD
  37. char dotdot[3*16+2] = "../../../../../../../../../../../../../../../../.";
  38. #include <mnttab.h>
  39. static char *getwd_buf;
  40. static int getwd_bufp;
  41.  
  42. char *
  43. getwd(buffer)
  44. char *buffer;
  45. {
  46.     getwd_buf = buffer;
  47.     getwd1(0);
  48.     if (getwd_bufp == 0)
  49.         getwd_buf[getwd_bufp++] = '/';
  50.     getwd_buf[getwd_bufp] = '\0';
  51.     return(getwd_buf);
  52. }
  53.  
  54. getwd1(n)
  55. int n;
  56. {
  57.     struct stat st, dev_st;
  58.     struct direct dir;
  59.     ino_t ino;
  60.     struct mnttab mnt;
  61.     FILE *fp;
  62.     register int i;
  63.     char buf[BUFSIZ];
  64.     static char dev_name[64];
  65.  
  66.     if (stat(dotdot+(16-n)*3, &st) < 0)
  67.         FEerror("Can't get the current working directory.", 0);
  68.     ino = st.st_ino;
  69.     if (ino == 2)
  70.         goto ROOT;
  71.     getwd1(n+1);
  72.     fp = fopen(dotdot+(16-n-1)*3, "r");
  73.     if (fp == NULL)
  74.         FEerror("Can't get the current working directory.", 0);
  75.     setbuf(fp, buf);
  76.     fread(&dir, sizeof(struct direct), 1, fp);
  77.     fread(&dir, sizeof(struct direct), 1, fp);
  78.     for (;;) {
  79.         if (fread(&dir, sizeof(struct direct), 1, fp) <= 0)
  80.             break;
  81.         if (dir.d_ino == ino)
  82.             goto FOUND;
  83.     }
  84.     fclose(fp);
  85.     FEerror("Can't get the current working directory.", 0);
  86.  
  87. FOUND:
  88.     fclose(fp);
  89.     getwd_buf[getwd_bufp++] = '/';
  90.     for (i = 0;  i < DIRSIZ && dir.d_name[i] != '\0';  i++)
  91.         getwd_buf[getwd_bufp++] = dir.d_name[i];
  92.     return;
  93.  
  94. ROOT:
  95.     fp = fopen("/etc/mnttab", "r");
  96.     if (fp == NULL)
  97.         FEerror("Can't get the current working directory.", 0);
  98.     setbuf(fp, buf);
  99.     for (;;) {
  100.         if (fread(&mnt, sizeof(struct mnttab), 1, fp) <= 0)
  101.             break;
  102.         if (mnt.mt_dev[0] != '/') {
  103.             strcpy(dev_name, "/dev/dsk/");
  104.             strcat(dev_name, mnt.mt_dev);
  105.             stat(dev_name, &dev_st);
  106.         } else
  107.             stat(mnt.mt_dev, &dev_st);
  108.         if (dev_st.st_rdev == st.st_dev)
  109.             goto DEV_FOUND;
  110.     }
  111.     fclose(fp);
  112.     getwd_bufp = 0;
  113.     return;
  114.  
  115. DEV_FOUND:
  116.     fclose(fp);
  117.     getwd_bufp = 0;
  118.     for (i = 0;  mnt.mt_filsys[i] != '\0';  i++)
  119.         getwd_buf[i] = mnt.mt_filsys[i];
  120.     /* BUG FIX by Grant J. Munsey */
  121.     if (i == 1 && *getwd_buf == '/')
  122.         i = 0;    /* don't add an empty directory name */
  123.     /* END OF BUG FIX */
  124.     getwd_bufp = i;
  125. }
  126. #endif   /* not GETCWD */
  127. #endif
  128.  
  129. #ifdef GETCWD
  130. char *
  131. getwd(buffer)
  132. char *buffer;
  133. {
  134.     char *getcwd();
  135.  
  136.     return(getcwd(buffer, MAXPATHLEN));
  137. }
  138. #endif
  139.  
  140. #ifdef DGUX
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192. #endif
  193.  
  194.  
  195. coerce_to_filename(pathname, p)
  196. object pathname;
  197. char *p;
  198. {
  199.   int n;
  200.   object namestring;
  201.   namestring = coerce_to_namestring(pathname);
  202.   if(namestring->st.st_self[0]=='~')
  203.     {char name[20];
  204.      int j;
  205.      object ans;
  206.      char *q = namestring->st.st_self;
  207.      extern struct passwd *getpwuid();
  208.      extern struct passwd *getpwnam();
  209.        
  210.      char filename[MAXPATHLEN];
  211.      struct passwd *pwent;
  212.      int m;
  213.      q=namestring->st.st_self;
  214.      for (n=0; n< namestring->st.st_fillp; n++)
  215.        if (q[n]=='/') break;
  216.      bcopy(q+1,name,n-1);
  217.      name[n-1]= 0;
  218.      pwent = (n==1 ? getpwuid(getuid()) : getpwnam(name));
  219.      if (pwent==0 || ((m = strlen(pwent->pw_dir))
  220.              && (m + namestring->st.st_fillp -n) >= MAXPATHLEN -16))
  221.        {FEerror("Can't expand pathname ~a", 1,namestring);}
  222.      bcopy(pwent->pw_dir,p,m);
  223.      bcopy(namestring->st.st_self+n,p+m,namestring->st.st_fillp-n);
  224.      p[m+namestring->st.st_fillp-n]=0;}
  225.   else
  226.     {if (namestring->st.st_fillp >= MAXPATHLEN - 16) {
  227.       vs_push(namestring);
  228.       FEerror("Too long filename: ~S.", 1, namestring);}
  229.      bcopy(namestring->st.st_self,p,namestring->st.st_fillp);
  230.      p[namestring->st.st_fillp]=0;}
  231. }
  232.  
  233. object
  234. truename(pathname)
  235. object pathname;
  236. {
  237.     register char *p, *q;
  238.     char filename[MAXPATHLEN];
  239.     char truefilename[MAXPATHLEN];
  240.     char current_directory[MAXPATHLEN];
  241.     char directory[MAXPATHLEN];
  242.     char *getwd();
  243.  
  244.     coerce_to_filename(pathname, filename);
  245.     for (p = filename, q = 0;  *p != '\0';  p++)
  246.         if (*p == '/')
  247.             q = p;
  248.     if (q == filename) {
  249.         q++;
  250.         getwd(current_directory);
  251.         p = "/";
  252.     } else if (q == 0) {
  253.         q = filename;
  254.         p = getwd(current_directory);
  255.     } else {
  256.         *q++ = '\0';
  257.         getwd(current_directory);
  258.         if (chdir(filename) < 0)
  259.             FEerror("Cannot get the truename of ~S.", 1, pathname);
  260.         p = getwd(directory);
  261.     }
  262.     if (p[0] == '/' && p[1] == '\0') {
  263.         if (strcmp(q, "..") == 0)
  264.             strcpy(truefilename, "/.");
  265.         else
  266.             sprintf(truefilename, "/%s", q);
  267.     } else if (strcmp(q, ".") == 0)
  268.         strcpy(truefilename, p);
  269.     else if (strcmp(q, "..") == 0) {
  270.         for (q = p + strlen(p);  *--q != '/';) ;
  271.         if (p == q)
  272.             strcpy(truefilename, "/.");
  273.         else {
  274.             *q = '\0';
  275.             strcpy(truefilename, p);
  276.             *q = '/';
  277.         }
  278.     } else
  279.         sprintf(truefilename, "%s/%s", p, q);
  280.     chdir(current_directory);
  281.     vs_push(make_simple_string(truefilename));
  282.     pathname = coerce_to_pathname(vs_head);
  283.     vs_pop;
  284.     return(pathname);
  285. }
  286.  
  287. bool
  288. file_exists(file)
  289. object file;
  290. {
  291.     char filename[MAXPATHLEN];
  292.     struct stat filestatus;
  293.  
  294.     coerce_to_filename(file, filename);
  295.     if (stat(filename, &filestatus) >= 0)
  296.       {
  297. #ifdef AIX
  298.         /* if /tmp/foo is not a directory /tmp/foo/ should not exist */
  299.         if (filename[strlen(filename)-1] == '/' &&
  300.         !( filestatus.st_mode & S_IFDIR))
  301.         return(FALSE);
  302. #endif        
  303.  
  304.         return TRUE;
  305.       }
  306.     
  307.     else
  308.         return(FALSE);
  309. }
  310.  
  311. FILE *
  312. backup_fopen(filename, option)
  313. char *filename,*option;
  314. {
  315.     char backupfilename[MAXPATHLEN];
  316.     char command[MAXPATHLEN * 2];
  317.  
  318.     strcat(strcpy(backupfilename, filename), ".BAK");
  319.     sprintf(command, "mv %s %s", filename, backupfilename);
  320.     system(command);
  321.     return(fopen(filename, option));
  322. }
  323.  
  324. int
  325. file_len(fp)
  326. FILE *fp;
  327. {
  328.     struct stat filestatus;
  329.  
  330.     fstat(fileno(fp), &filestatus);
  331.     return(filestatus.st_size);
  332. }
  333.  
  334. Ltruename()
  335. {
  336.     check_arg(1);
  337.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  338.     vs_base[0] = truename(vs_base[0]);
  339. }
  340.  
  341. Lrename_file()
  342. {
  343.     char filename[MAXPATHLEN];
  344.     char newfilename[MAXPATHLEN];
  345.     char command[MAXPATHLEN * 2];
  346.  
  347.     check_arg(2);
  348.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  349.     check_type_or_Pathname_string_symbol(&vs_base[1]);
  350.     coerce_to_filename(vs_base[0], filename);
  351.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  352.     vs_base[1] = coerce_to_pathname(vs_base[1]);
  353.     vs_base[1] = merge_pathnames(vs_base[1], vs_base[0], Cnil);
  354.     coerce_to_filename(vs_base[1], newfilename);
  355. #ifdef BSD
  356.     if (rename(filename, newfilename) < 0)
  357.         FEerror("Cannot rename the file ~S to ~S.",
  358.             2, vs_base[0], vs_base[1]);
  359. #else
  360.     sprintf(command, "mv %s %s", filename, newfilename);
  361.     system(command);
  362. #endif
  363.     vs_push(vs_base[1]);
  364.     vs_push(truename(vs_base[0]));
  365.     vs_push(truename(vs_base[1]));
  366.     vs_base += 2;
  367. }
  368.  
  369. Ldelete_file()
  370. {
  371.     char filename[MAXPATHLEN];
  372.  
  373.     check_arg(1);
  374.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  375.     coerce_to_filename(vs_base[0], filename);
  376.     if (unlink(filename) < 0)
  377.         FEerror("Cannot delete the file ~S.", 1, vs_base[0]);
  378.     vs_base[0] = Ct;
  379. }
  380.  
  381. Lprobe_file()
  382. {
  383.     check_arg(1);
  384.  
  385.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  386.     if (file_exists(vs_base[0]))
  387.         vs_base[0] = truename(vs_base[0]);
  388.     else
  389.         vs_base[0] = Cnil;
  390. }
  391.  
  392. Lfile_write_date()
  393. {
  394.     char filename[MAXPATHLEN];
  395.     struct stat filestatus;
  396.  
  397.     check_arg(1);
  398.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  399.     coerce_to_filename(vs_base[0], filename);
  400.     if (stat(filename, &filestatus) < 0) { vs_base[0] = Cnil; return;}
  401.     vs_base[0] = unix_time_to_universal_time(filestatus.st_mtime);
  402. }
  403.  
  404. Lfile_author()
  405. {
  406.     char filename[MAXPATHLEN];
  407.     struct stat filestatus;
  408.     struct passwd *pwent;
  409.     extern struct passwd *getpwuid();
  410.  
  411.     check_arg(1);
  412.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  413.     coerce_to_filename(vs_base[0], filename);
  414.     if (stat(filename, &filestatus) < 0) { vs_base[0] = Cnil; return;}
  415.     pwent = getpwuid(filestatus.st_uid);
  416.     vs_base[0] = make_simple_string(pwent->pw_name);
  417. }
  418.  
  419. Luser_homedir_pathname()
  420. {
  421.     struct passwd *pwent;
  422.     char filename[MAXPATHLEN];
  423.     register int i;
  424.     extern struct passwd *getpwuid();
  425.  
  426.     if (vs_top - vs_base > 1)
  427.         too_many_arguments();
  428.     pwent = getpwuid(getuid());
  429.     strcpy(filename, pwent->pw_dir);
  430.     i = strlen(filename);
  431.     if (filename[i-1] != '/') {
  432.         filename[i++] = '/';
  433.         filename[i] = '\0';
  434.     }
  435.     vs_base[0] = make_simple_string(filename);
  436.     vs_top = vs_base+1;
  437.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  438. }
  439.  
  440.  
  441. #ifdef BSD
  442. Ldirectory()
  443. {
  444.     char filename[MAXPATHLEN];
  445.     char command[MAXPATHLEN * 2];
  446.     FILE *fp;
  447.     register i, c;
  448.     object *top = vs_top;
  449.     char iobuffer[BUFSIZ];
  450.     extern FILE *popen();
  451.  
  452.     check_arg(1);
  453.  
  454.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  455.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  456.     if (vs_base[0]->pn.pn_name==Cnil && vs_base[0]->pn.pn_type==Cnil) {
  457.         coerce_to_filename(vs_base[0], filename);
  458.         strcat(filename, "*");
  459.     } else if (vs_base[0]->pn.pn_name==Cnil) {
  460.         vs_base[0]->pn.pn_name = Kwild;
  461.         coerce_to_filename(vs_base[0], filename);
  462.         vs_base[0]->pn.pn_name = Cnil;
  463.     } else if (vs_base[0]->pn.pn_type==Cnil) {
  464.         coerce_to_filename(vs_base[0], filename);
  465.         strcat(filename, "*");
  466.     } else
  467.         coerce_to_filename(vs_base[0], filename);
  468.     sprintf(command, "ls -d %s 2> /dev/null", filename);
  469.     fp = popen(command, "r");
  470.     setbuf(fp, iobuffer);
  471.     for (;;) {
  472.         for (i = 0;  c = getc(fp);  i++)
  473.             if (c <= 0)
  474.                 goto L;
  475.             else if (c == '\n')
  476.                 break;
  477.             else
  478.                 filename[i] = c;
  479.         filename[i] = '\0';
  480.         vs_push(make_simple_string(filename));
  481.         vs_head = truename(vs_head);
  482.     }
  483. L:
  484.     pclose(fp);
  485.     vs_push(Cnil);
  486.     while (vs_top > top + 1)
  487.         stack_cons();
  488.     vs_base = top;
  489. }
  490. #endif
  491.  
  492.  
  493. #ifdef ATT
  494. Ldirectory()
  495. {
  496.     object name, type;
  497.     char filename[MAXPATHLEN];
  498.     FILE *fp;
  499.     object *top = vs_top;
  500.     char iobuffer[BUFSIZ];
  501.     struct direct dir;
  502.     int i;
  503.  
  504.     check_arg(1);
  505.  
  506.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  507.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  508.     vs_push(vs_base[0]->pn.pn_name);
  509.     vs_push(vs_base[0]->pn.pn_type);
  510.     vs_base[0]->pn.pn_name = Cnil;
  511.     vs_base[0]->pn.pn_type = Cnil;
  512.     coerce_to_filename(vs_base[0], filename);
  513.     type = vs_base[0]->pn.pn_type = vs_pop;
  514.     name = vs_base[0]->pn.pn_name = vs_pop;
  515.     i = strlen(filename);
  516.     if (i > 1 && filename[i-1] == '/')
  517.         filename[i-1] = '\0';
  518.     if (i == 0)
  519.         strcpy(filename, ".");
  520.     fp = fopen(filename, "r");
  521.     if (fp == NULL) {
  522.         vs_push(make_simple_string(filename));
  523.         FEerror("Can't open the directory ~S.", 1, vs_head);
  524.     }
  525.     setbuf(fp, iobuffer);
  526.     fread(&dir, sizeof(struct direct), 1, fp);
  527.     fread(&dir, sizeof(struct direct), 1, fp);
  528.     filename[DIRSIZ] = '\0';
  529.     for (;;) {
  530.         if (fread(&dir, sizeof(struct direct), 1, fp) <=0)
  531.             break;
  532.         if (dir.d_ino == 0)
  533.             continue;
  534.         strncpy(filename, dir.d_name, DIRSIZ);
  535.         vs_push(make_simple_string(filename));
  536.         vs_head = coerce_to_pathname(vs_head);
  537.         if ((name == Cnil || name == Kwild ||
  538.              equal(name, vs_head->pn.pn_name)) &&
  539.             (type == Cnil || type == Kwild ||
  540.              equal(type, vs_head->pn.pn_type))) {
  541.             vs_head->pn.pn_directory
  542.             = vs_base[0]->pn.pn_directory;
  543.             vs_head = truename(vs_head);
  544.         } else
  545.             vs_pop;
  546.     }
  547.     fclose(fp);
  548.     vs_push(Cnil);
  549.     while (vs_top > top + 1)
  550.         stack_cons();
  551.     vs_base = top;
  552. }
  553. #endif
  554.  
  555.  
  556. #ifdef E15
  557. #include <sys/dir.h>
  558. Ldirectory()
  559. {
  560.     object name, type;
  561.     char filename[MAXPATHLEN];
  562.     FILE *fp;
  563.     object *top = vs_top;
  564.     char iobuffer[BUFSIZ];
  565.     struct direct dir;
  566.     int i;
  567.  
  568.     check_arg(1);
  569.  
  570.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  571.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  572.     vs_push(vs_base[0]->pn.pn_name);
  573.     vs_push(vs_base[0]->pn.pn_type);
  574.     vs_base[0]->pn.pn_name = Cnil;
  575.     vs_base[0]->pn.pn_type = Cnil;
  576.     coerce_to_filename(vs_base[0], filename);
  577.     type = vs_base[0]->pn.pn_type = vs_pop;
  578.     name = vs_base[0]->pn.pn_name = vs_pop;
  579.     i = strlen(filename);
  580.     if (i > 1 && filename[i-1] == '/')
  581.         filename[i-1] = '\0';
  582.     if (i == 0)
  583.         strcpy(filename, ".");
  584.     fp = fopen(filename, "r");
  585.     if (fp == NULL) {
  586.         vs_push(make_simple_string(filename));
  587.         FEerror("Can't open the directory ~S.", 1, vs_head);
  588.     }
  589.     setbuf(fp, iobuffer);
  590.     fread(&dir, sizeof(struct direct), 1, fp);
  591.     fread(&dir, sizeof(struct direct), 1, fp);
  592.     filename[DIRSIZ] = '\0';
  593.     for (;;) {
  594.         if (fread(&dir, sizeof(struct direct), 1, fp) <=0)
  595.             break;
  596.         if (dir.d_ino == 0)
  597.             continue;
  598.         strncpy(filename, dir.d_name, DIRSIZ);
  599.         vs_push(make_simple_string(filename));
  600.         vs_head = coerce_to_pathname(vs_head);
  601.         if ((name == Cnil || name == Kwild ||
  602.              equal(name, vs_head->pn.pn_name)) &&
  603.             (type == Cnil || type == Kwild ||
  604.              equal(type, vs_head->pn.pn_type))) {
  605.             vs_head->pn.pn_directory
  606.             = vs_base[0]->pn.pn_directory;
  607.             vs_head = truename(vs_head);
  608.         } else
  609.             vs_pop;
  610.     }
  611.     fclose(fp);
  612.     vs_push(Cnil);
  613.     while (vs_top > top + 1)
  614.         stack_cons();
  615.     vs_base = top;
  616. }
  617. #endif
  618.  
  619.  
  620. #ifdef DGUX
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669. #endif
  670.  
  671. siLchdir()
  672. {
  673.     char filename[MAXPATHLEN];
  674.  
  675.     check_arg(1);
  676.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  677.     coerce_to_filename(vs_base[0], filename);
  678.     if (chdir(filename) < 0)
  679.         FEerror("Can't change the current directory to ~S.",
  680.             1, vs_base[0]);
  681. }
  682.  
  683. init_unixfsys()
  684. {
  685.     make_function("TRUENAME", Ltruename);
  686.     make_function("RENAME-FILE", Lrename_file);
  687.     make_function("DELETE-FILE", Ldelete_file);
  688.     make_function("PROBE-FILE", Lprobe_file);
  689.     make_function("FILE-WRITE-DATE", Lfile_write_date);
  690.     make_function("FILE-AUTHOR", Lfile_author);
  691.     make_function("USER-HOMEDIR-PATHNAME", Luser_homedir_pathname);
  692.     make_function("DIRECTORY", Ldirectory);
  693.  
  694.     make_si_function("CHDIR", siLchdir);
  695. }
  696.